/**
* @file         nrf24l01.c
* @brief		本文件定义了NRF24L01的驱动代码
* @details	    This is the detail description.
* @author		Hang
* @date		    2024/05/18
* @version	    v1.0
* @par Copyright(c): 	none
* @par History:
*	version: Hang, 2024/05/18, Driver of NRF24L01\n
*/

#include "nrf24l01.h"

#include <sys/stat.h>

/**
* Function: nrf24l01Transmit
* Description: 通过SPI协议向NRF24L01传输一些数据
* Input: pTxData - 发送数据缓冲区
* Output: pRxData - 接收数据缓冲区
* Returns: 无
*/
static void nrf24l01Transmit(uint8_t *pTxData, uint8_t *pRxData, uint16_t Len) {
    for( int i = 0; i < Len; ++i ) {
        uint8_t tempValue = 0;
        for( int j = 0; j < 8; ++j ) {
            if( pTxData[i] & ( 0x80 >> j ) ) {
                __NRF24L01_MOSI_SET();
            }else {
                __NRF24L01_MOSI_RESET();
            }
            __NRF24L01_SCK_SET();
            if( __IS_NRF24L01_MISO_SET() ) {
                tempValue |= ( 0x80 >> i );
            }
            __NRF24L01_SCK_RESET();
        }
        pRxData[i] = tempValue;
    }
}
/**
* Function: nrf24l01WriteRegister
* Description: NRF24L01向寄存器写数据的函数
* Input: Register - 要写入的寄存器
*        Value - 要写入对应寄存器的值
* Output: 无
* Returns: 无
*/
static void nrf24l01WriteRegister(uint8_t Register, uint8_t Value) {
    uint8_t tempRegister = ( NRF_CMD_W_REGISTER | Register );
    uint8_t tempValue = NRF_CMD_NOP;

    __NRF24L01_CSN_RESET();

    nrf24l01Transmit(&tempRegister, &tempValue, 1);
    nrf24l01Transmit(&Value, &tempValue, 1);

    __NRF24L01_CSN_SET();
}
/**
* Function: nrf24l01ReadRegister
* Description: NRF24L01从某寄存器读取数据
* Input: Register - 要读取数据的寄存器
* Output: Value - 从对应寄存器读取到的值
* Returns: 无
*/
static void nrf24l01ReadRegister(uint8_t Register, uint8_t *Value) {
    uint8_t tempRegister = ( NRF_CMD_R_REGISTER | Register );
    uint8_t tempValue[2] = { NRF_CMD_NOP, NRF_CMD_NOP };

    __NRF24L01_CSN_RESET();

    nrf24l01Transmit(&tempRegister, &tempValue[1], 1);
    nrf24l01Transmit(&tempValue[0], Value, 1);

    __NRF24L01_CSN_SET();
}
/**
* Function: nrf24l01WriteBuffer
* Description: NRF24L01一次写多个数据到制定寄存器
* Input: Register - 要写入的寄存器
*        pBuffer - 要发送的数据缓冲区
*        Len - 要发送数据的长度
* Output: 无
* Returns: 无
*/
static void nrf24l01WriteBuffer(uint8_t Register, uint8_t *pBuffer, uint16_t Len) {
    uint8_t tempRegister = ( NRF_CMD_W_REGISTER | Register );
    uint8_t *tempBuffer = (uint8_t *)malloc( ( Len + 1 ) * sizeof(uint8_t) );
    assert(tempBuffer);

    __NRF24L01_CSN_RESET();

    nrf24l01Transmit(&tempRegister, &tempBuffer[Len], 1);
    nrf24l01Transmit(pBuffer, tempBuffer, Len);

    __NRF24L01_CSN_SET();

    free(tempBuffer);
}
/**
* Function: nrf24l01ReadBuffer
* Description: NRF24L01从指定寄存器读取多个数据
* Input: Register - 要写入的寄存器
*        Len - 要接收数据的长度
* Output: pBuffer - 数据接收缓冲区
* Returns: 无
*/
static void nrf24l01ReadBuffer(uint8_t Register, uint8_t *pBuffer, uint16_t Len) {
    uint8_t tempRegister = ( NRF_CMD_W_REGISTER | Register );
    uint8_t *tempBuffer = (uint8_t *)malloc( ( Len + 1 ) * sizeof(uint8_t) );
    assert(tempBuffer);

    for( int i = 0; i <= Len; ++i ) {
        tempBuffer[i] = NRF_CMD_NOP;
    }

    __NRF24L01_CSN_RESET();

    nrf24l01Transmit(&tempRegister, &tempBuffer[Len], 1);
    nrf24l01Transmit(tempBuffer, pBuffer, Len);

    __NRF24L01_CSN_SET();

    free(tempBuffer);
}
/**
* Function: nrf24l01SetTxAddress
* Description: 设置NRF24L01的发送地址
* Input: pDevice - NRF24L01设备指针
* Output: 无
* Returns: 无
*/
void nrf24l01SetTxAddress(nrf24l01Dev_t *pDevice) {
    nrf24l01WriteBuffer(NRF_REG_TX_ADDR, pDevice->txAddr, TX_ADDR_SIZE );
}
/**
* Function: nrf24l01SetRxAddress
* Description: 设置NRF24L01的接收地址
* Input: pDevice - NRF24L01设备指针
* Output: 无
* Returns: 无
*/
void nrf24l01SetRxAddress(nrf24l01Dev_t *pDevice) {
    nrf24l01WriteBuffer(NRF_REG_RX_ADDR_P0, pDevice->rxAddr, RX_ADDR_SIZE );
}
/**
* Function: nrf24l01CleanRxBuffer
* Description: 清除接收缓冲区的数据
* Input: 无
* Output: 无
* Returns: 无
*/
void nrf24l01CleanRxBuffer() {
    uint8_t tempCmd[2] = {NRF_CMD_FLUSH_RX, NRF_CMD_NOP};
    uint8_t tempValue[2] = { 0 };
    __NRF24L01_CSN_RESET();

    nrf24l01Transmit(tempCmd, tempValue, sizeof(tempCmd) / sizeof(tempCmd[0]));

    __NRF24L01_CSN_SET();
}
/**
* Function: nrf24l01Initialize
* Description: 初始化NRF24L01设备
* Input: pDevice - NRF24L01设备指针
* Output: 无
* Returns: 无
*/
void nrf24l01Initialize(nrf24l01Dev_t *pDevice) {
    /* 初始化GPIO */
    /* 将由STM32CubueMX生成 */

    /* 配置NRF24L01的运行参数 */
    __NRF24L01_CE_RESET();

    nrf24l01SetTxAddress(pDevice);
    nrf24l01SetRxAddress(pDevice);

    nrf24l01WriteRegister(NRF_REG_CONFIG, 0x0F);//配置成接收模式
    nrf24l01WriteRegister(NRF_REG_EN_AA, 0x01);//通道0开启自动应答
    nrf24l01WriteRegister(NRF_REG_RF_CH, 0x00);//配置通信频率2.4G
    nrf24l01WriteRegister(NRF_REG_RX_PW_P0, 32);//配置接收通道0接收的数据宽度32字节
    nrf24l01WriteRegister(NRF_REG_EN_RXADDR, 0x01);//接收通道0使能
    nrf24l01WriteRegister(NRF_REG_SETUP_RETR, 0x1A);//配置580us重发时间间隔,重发10次
    nrf24l01CleanRxBuffer();
    //nrf24l01WriteRegister(NRF_CMD_FLUSH_RX, NRF_CMD_NOP);

    __NRF24L01_CE_SET();
}

uint8_t readStatusRegister() {
    uint8_t status_val;
    nrf24l01ReadRegister(NRF_REG_STATUS,&status_val);
    return status_val;
}

bool isRxDataReady(uint8_t status) {
    return (status & STATUS_RX_DR) == STATUS_RX_DR;
}

bool isTxDataSucess(uint8_t status) {
    return (status & STATUS_TX_DS) == STATUS_TX_DS;
}

bool isMaxResend(uint8_t status) {
    return (status & STATUS_MAX_RT) == STATUS_MAX_RT;
}

bool isTxFull(uint8_t status) {
    return (status & STATUS_TX_FULL) == STATUS_TX_FULL;
}

StatusRegRxPipe getRxPipe(uint8_t status) {
    StatusRegRxPipe pipe = (StatusRegRxPipe)((status & STATUS_RX_P_NO) >> 1);
    return pipe;
}

/**
* Function: isConnected
* Description: 检查NRF24L01是否连接成功
* Input: 无
* Output: 无
* Returns: true - NRF24L01设备连接成功
*          false - NRF24L01设备连接失败
*/
bool isConnected() {
    uint8_t test_config_value = 0x0F, read_config_value = 0xAA;

    nrf24l01WriteRegister(NRF_REG_CONFIG, test_config_value);

    nrf24l01ReadRegister(NRF_REG_CONFIG, &read_config_value);

    return test_config_value == read_config_value ? true : false;
}

void nrf24l01Send(nrf24l01Dev_t *pDevice) {

}

void nrf24l01Receive(nrf24l01Dev_t *pDevice) {
    uint8_t status = readStatusRegister();
    if(isRxDataReady(status)) {
        nrf24l01ReadBuffer(NRF_CMD_R_RX_PAYLOAD, pDevice->rxBuff, RX_BUFF_SIZE);
    }
}
